package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.service.AuditService;
import com.atguigu.tingshu.album.service.FileUploadService;
import com.atguigu.tingshu.common.execption.GuiguException;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.UUID;

/**
 * @author: atguigu
 * @create: 2025-07-18 09:41
 */
@Slf4j
@Service
public class FileUploadServiceImpl implements FileUploadService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConstantProperties minioConstantProperties;

    @Autowired
    private AuditService auditService;


    /**
     * 将图片（专辑声音封面、用户头像）文件上传到MInIO
     *
     * @param file 图片文件
     * @return MInIO文件在线地址
     */
    @Override
    public String uploadFile(MultipartFile file) throws IOException {
        //1.业务校验：校验图片文件格式是否合法
        BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
        if (bufferedImage == null) {
            throw new GuiguException(500, "图片文件格式不合法");
        }

        //2.业务校验：校验图片文件大小是否合法 业务限制避免上传高清图片
        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        if (width > 900 || height > 900) {
            throw new GuiguException(500, "图片文件大小不合法");
        }

        //TODO 对图片进行审核
        String suggestion = auditService.auditImage(file);
        if ("block".equals(suggestion) || "review".equals(suggestion)) {
            throw new GuiguException(500, "图片违规");
        }

        //3.将图片文件上传MINIO 规范：日期/文件唯一命名.后缀
        //3.1 生成日期作为文件夹名称
        String folderName = DateUtil.today();

        //3.2 生成文件唯一名称
        String extName = FileUtil.extName(file.getOriginalFilename());
        String objectName = "/" + folderName + "/" + UUID.randomUUID().toString() + "." + extName;

        //3.3 上传文件
        try {
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(minioConstantProperties.getBucketName()).object(objectName).stream(
                                    file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
        } catch (Exception e) {
            log.error("上传文件到MINIO失败：{}", e.getMessage());
            throw new GuiguException(500, "上传文件到MINIO失败");
        }

        //4.拼接MINIO文件在线地址
        return minioConstantProperties.getEndpointUrl() + "/" + minioConstantProperties.getBucketName() + objectName;
    }
}
